
import os
import sys
import re
import collections

class CFGAdv:
    def __init__(self):
      self.cfg = ''
      self.isInherited = False

    def setCFGDir(self, cfgDir):
      self.cfgDir = cfgDir

    def setInheritedSys(self, isInherited):
      self.isInherited = isInherited

    def __inheritSys(self,vars):
      if self.isInherited == False: return 
      
      for k,v in os.environ.items():
        vars[k] = v

    def __readCFG(self,cfgFile,vars):
      includes = collections.OrderedDict()
      cfgFile = os.path.join(self.cfgDir,cfgFile)

      try:
        cfg = open(cfgFile,'r')
        
        includeReg = '^\s*(.include)\s*=\s*(\S+)\s*$'
        varReg = '^\s*(\w+)\s*=\s*(\S+)\s*$'
        for line in cfg:
          line = line.strip()
          # comment
          if line.startswith('#') or line == '' : continue
          # var definition 
          varObj = re.match(varReg, line)
          if varObj != None: 
            vars[varObj.group(1)] = varObj.group(2)
            continue
          # include sub config file
          includeObj = re.match(includeReg, line)
          if includeObj != None: 
            subIncludes = self.__readCFG(includeObj.group(2),vars)
            #for key, value in includeVars.items(): vars[key] = value
            includes[includeObj.group(2)] = subIncludes
            continue

      except IOError as e:
        sys.stdout.write(str(e))
        
      return includes

    def __resolveVars(self,vars):
      varSep = '%'
      varSepReg = '[^\\\\]*' + varSep
      varReg = varSepReg + '(\w+)' + varSepReg
      #[^\\]*%(\w+)[^\\]*%
      undefinedVars = list()

      for key,value in vars.items():
        find = True;defined = True
        while(find and defined):
          varlist = re.findall(varReg,value)
          if(len(varlist)) < 1: find = False
          else:
            print(varlist)
            for var in varlist:
              if not var in vars.keys(): 
                undefinedVars.append(var)
                defined = False
              else:
                value = re.sub(varSep + var + varSep,vars[var],value)
        vars[key] = value
        
      return undefinedVars
      
    def __overwriteVars(self,vars,overwriteVars):
      for key, value in overwriteVars:
        vars[key] = value     

    def readCFG(self, cfgFile, overwriteVars = {}):
      vars = collections.OrderedDict()
      self.__inheritSys(vars)
      includes = self.__readCFG(cfgFile,vars)
      undefinedVars = self.__resolveVars(vars)
      self.__overwriteVars(vars,overwriteVars)
      
      return vars,includes,undefinedVars

def testCFGAdv():
    mycfg = CFGAdv()
    mycfg.setCFGDir(os.getcwd())
    #mycfg.setInheritedSys(True)
    vars,includes,undefinedVars  = mycfg.readCFG('test.cfg')
    for k,v in vars.items():
      print(k + '=' + v)
    print(includes)
    print(undefinedVars)
    
testCFGAdv()
